package com.fingard.dsp.bank.directbank.weixin01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.RefundState;
import com.fingard.dsp.bank.directbank.bankInterface.IRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsRecRefund;
import com.fingard.text.StringHelper;
import com.fingard.text.XmlHelper;
import com.fingard.xml.XmlTextReader;

import java.util.ArrayList;

public class WEIXIN01RecRefund extends WEIXIN01Base implements IRecRefund {
	@Override
	public RetAtsRecRefund submitRecRefund(ReqRecRefund p_reqRef) throws Exception {
		RetAtsRecRefund retAts = new RetAtsRecRefund();
		retAts.oriRdSeq = p_reqRef.oriRdSeq;
		retAts.refundNo = p_reqRef.refundNo;
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
			if (actItem != null) {
				ArrayList<String> arrayParams = new ArrayList<String>();
				
				StringBuilder sbXml = new StringBuilder();
				sbXml.append("<xml>\r\n");
				
				String appid = actItem.appId;
				sbXml.append("  <appid>" + appid + "</appid>\r\n");
				arrayParams.add("appid=" + appid);

				String mch_id = actItem.merchantId;
				sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
				arrayParams.add("mch_id=" + mch_id);

				String nonce_str = get_nonce_str();
				sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
				arrayParams.add("nonce_str=" + nonce_str);
				
				sbXml.append("  <sign_type>" + "MD5" + "</sign_type>\r\n");
				arrayParams.add("sign_type=" + "MD5");
				
				sbXml.append("  <transaction_id></transaction_id>\r\n");
//				arrayParams.add("transaction_id=");
				
				String outTradeNo = p_reqRef.oriRdSeq;
				sbXml.append("  <out_trade_no>" + outTradeNo + "</out_trade_no>\r\n");
				arrayParams.add("out_trade_no=" + outTradeNo);
				
				String refundNo = p_reqRef.refundNo;
				if (StringHelper.hasAnyChar(refundNo)) {
					sbXml.append("  <out_refund_no>" + refundNo + "</out_refund_no>\r\n");
					arrayParams.add("out_refund_no=" + refundNo);
				}

				String totalFee = p_reqRef.totalAmt;
                if (StringHelper.hasAnyChar(totalFee)) {
                    totalFee = StringHelper.amountMultiply100(totalFee);
                    sbXml.append("  <total_fee>" + totalFee + "</total_fee>\r\n");
                    arrayParams.add("total_fee=" + totalFee);
                }

				String refundAmt = p_reqRef.amount;
				if (StringHelper.hasAnyChar(refundAmt)) {
					refundAmt = StringHelper.amountMultiply100(refundAmt);
					sbXml.append("  <refund_fee>" + refundAmt + "</refund_fee>\r\n");
					arrayParams.add("refund_fee=" + refundAmt);
				}
				
				sbXml.append("  <refund_fee_type></refund_fee_type>\r\n");
//				arrayParams.add("refund_fee=" + refundAmt);
				
				String decription = p_reqRef.decription;
				if (StringHelper.hasAnyChar(decription)) {
					decription = XmlHelper.encode(decription);
					sbXml.append("  <refund_desc>" + decription + "</refund_desc>\r\n");
					arrayParams.add("refund_desc=" + decription);
				}
				
				sbXml.append("  <refund_account>REFUND_SOURCE_UNSETTLED_FUNDS</refund_account>\r\n");
				arrayParams.add("refund_account=REFUND_SOURCE_UNSETTLED_FUNDS");
				
				String notifyUrl = actItem.notifyURL;
				if (StringHelper.hasAnyChar(notifyUrl)) {
					sbXml.append("  <notify_url>" + notifyUrl + "</notify_url>\r\n");
					arrayParams.add("notify_url=" + notifyUrl);
				}
				
				String[] signParams = new String[arrayParams.size()];
				arrayParams.toArray(signParams);
				
				String sign = signMessage(signParams, actItem.saltKey);
				sbXml.append("  <sign>" + sign + "</sign>\r\n");
				sbXml.append("</xml>");
				
				String[] tmpStrRet = sendToBank(sbXml.toString(), "submitRecRefund", actItem);

				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1],	tmpSbMsg);
					
					if (tmpBkReader != null) {
						String return_code = tmpBkReader.getFirstText("/xml/return_code");
						String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
						String result_code = tmpBkReader.getFirstText("/xml/result_code");
						if (return_code != null && return_code.equals("SUCCESS")) {
							retAts.respCode = "0";
							if (result_code != null	&& result_code.equals("SUCCESS")) {
								boolean verifyResult = this.verifySign(tmpStrRet[1], actItem.saltKey, tmpSbMsg);
								if (verifyResult) {
									retAts.respInfo = return_msg;
									retAts.refundState = RefundState.REFUND_PAYING;
									retAts.oriOppOrderNo = tmpBkReader.getFirstText("/xml/transaction_id");
									retAts.oppRefundNo = tmpBkReader.getFirstText("/xml/refund_id");
									retAts.originalCode = result_code;
									retAts.originalInfo = "成功";
									retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", result_code);
								} else {
									retAts.respCode = "-1";
									retAts.respInfo = tmpSbMsg.toString();
								}
							} else {
								retAts.refundState = RefundState.REFUND_FAIL;
								retAts.originalCode = tmpBkReader.getFirstText("/xml/err_code");
								retAts.originalInfo = tmpBkReader.getFirstText("/xml/err_code_des");
								retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", retAts.originalCode);
								retAts.respInfo = retAts.originalInfo;
							}
						} else {
							retAts.respCode = "-1";
							retAts.respInfo = return_msg;
						}
					} else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpSbMsg.toString();
					}
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = tmpStrRet[1];
				}
			} else {
				retAts.respCode = "0";
				retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
				retAts.refundState = RefundState.REFUND_FAIL;
				retAts.originalCode = "E9981";
				retAts.originalInfo = retAts.respInfo;
				retAts.unifiedCode = "E9981";
			}
		} catch(Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		return retAts;
	}

	@Override
	public RetAtsQryRecRefund queryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
		RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
		retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
		retAts.refundNo = p_reqQryRef.refundNo;
		
		try {
			ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
			if (actItem != null) {
				ArrayList<String> arrayParams = new ArrayList<String>();

				StringBuilder sbXml = new StringBuilder();
				sbXml.append("<xml>\r\n");
				
				String appid = actItem.appId;
				sbXml.append("  <appid>" + appid + "</appid>\r\n");
				arrayParams.add("appid=" + appid);

				String mch_id = actItem.merchantId;
				sbXml.append("  <mch_id>" + mch_id + "</mch_id>\r\n");
				arrayParams.add("mch_id=" + mch_id);
				
				String nonce_str = get_nonce_str();
				sbXml.append("  <nonce_str>" + nonce_str + "</nonce_str>\r\n");
				arrayParams.add("nonce_str=" + nonce_str);

				sbXml.append("  <sign_type>" + "MD5" + "</sign_type>\r\n");
				arrayParams.add("sign_type=" + "MD5");
				
				String outTradeNo = p_reqQryRef.oriRdSeq;
				if (StringHelper.hasAnyChar(outTradeNo)) {
					sbXml.append("  <out_trade_no>" + outTradeNo + "</out_trade_no>\r\n");
					arrayParams.add("out_trade_no=" + outTradeNo);
				}
				
				String refundNo = p_reqQryRef.refundNo;
				if (StringHelper.hasAnyChar(refundNo)) {
					sbXml.append("  <out_refund_no>" + refundNo + "</out_refund_no>\r\n");
					arrayParams.add("out_refund_no=" + refundNo);
				}

				String[] signParams = new String[arrayParams.size()];
				arrayParams.toArray(signParams);
				
				String sign = signMessage(signParams, actItem.saltKey);
				sbXml.append("  <sign>" + sign + "</sign>\r\n");
				sbXml.append("</xml>");
				
				String[] tmpStrRet = sendToBank(sbXml.toString(), "queryRecRefund", actItem);
				
				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1],	tmpSbMsg);
					if (tmpBkReader != null) {
						String return_code = tmpBkReader.getFirstText("/xml/return_code");
						String return_msg = tmpBkReader.getFirstText("/xml/return_msg");
						if (return_code != null && return_code.equals("SUCCESS")) {
							String err_code = tmpBkReader.getFirstText("/xml/err_code");
							String err_msg = tmpBkReader.getFirstText("/xml/err_code_des");
							retAts.respCode = "0";
							retAts.respInfo = return_msg;
							if (StringHelper.hasAnyChar(err_msg)) {
								retAts.respInfo = err_msg;
							}

							retAts.oriOppOrderNo = tmpBkReader.getFirstText("/xml/transaction_id");
							retAts.oppRefundNo = tmpBkReader.getFirstText("/xml/refund_id_0");
							retAts.refundChannel = tmpBkReader.getFirstText("/xml/refund_channel");
							retAts.refundRecAccount = tmpBkReader.getFirstText("/xml/refund_recv_accout_0");
							retAts.refundSuccessDate = tmpBkReader.getFirstText("/xml/refund_success_time_0");

							String refundState = tmpBkReader.getFirstText("/xml/refund_status_0");
							if ("SUCCESS".equals(refundState)) {
								retAts.refundState = RefundState.REFUND_SUCCESS;
							} else if ("REFUNDCLOSE".equals(refundState)) {
								retAts.refundState = RefundState.REFUND_CLOSED;
							} else if ("PROCESSING".equals(refundState)) {
								retAts.refundState = RefundState.REFUND_PAYING;
							} else {
								retAts.refundState = RefundState.REFUND_FAIL;
							}

							if (StringHelper.hasAnyChar(err_code)) {
								retAts.originalCode = err_code;
								retAts.originalInfo = err_msg;
								retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", err_code);
							} else {
								retAts.originalCode = refundState;
								retAts.originalInfo = retAts.respInfo;
								retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", refundState);
							}
						} else {
							retAts.respCode = "-1";
							retAts.respInfo = return_msg;
						}
					} else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpSbMsg.toString();
					}
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = tmpStrRet[1];
				}
			} else {
				retAts.respCode = "-1";
				retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		return retAts;
	}
}